#ifndef THEATER_H
#include "utility.h"

#define NUM_GROUP 10

#define MAX_NAME 40 
#define MAX_CR 100
#define MIN_CR 40  /* Customers*/
#define MAX_TC 5  /* TicketClerks*/
#define MAX_CC 5  /* ConcessionClerks*/
#define MAX_TT 3  /* TicketTakers*/
#define MAX_MT 1  /* MovieTechnician*/
#define MAX_MR 1  /* Manager*/

#define true 1
#define false 0

#define ALREADY_HAVE 2

#define MAX_GROUP 10  /*  Group */
#define MIN_GROUP 10  /*  Group */
#define MAX_GROUPSIZE 5  /*  groupsize */

#define MAX_CR_NUMBER 100  /*  Group */
#define MAX_GP_NUMBER 100  /*  Group */

#define MAX_VAR 200

#define RATE_POPCORN 0.75  /*  chance to buy Popcorn */
#define RATE_SODA 0.75  /*  chance to buy Soda */
#define RATE_BATHROOM 0.25  /*  chance to go bathroom */

#define PRICE_TICKET 12  /* ticket price */
#define PRICE_SODA 4     /* soda price */
#define PRICE_POPCORN 5  /* popcorn price */

#define FOOD_POPCORN 0
#define FOOD_SODA    1

#define MOVIE_PERIOD_BASE  200
#define MOVIE_PERIOD_VAR  100

#define MAX_SEAT   25  /*  capacity of theater room */
#define MAX_ROW    5   /*  theater room max row */
#define MAX_COL    5  /*  theater room max col */

/*struct define, struct for the ticketclerk*/
typedef  struct
{
    char isBusy[MAX_NAME];
    char isBreak[MAX_NAME];
    int id;
    /* group on service*/
    char  groupId[MAX_NAME];
    /* customer in waiting line*/
    char waitingSize[MAX_NAME];
    char  lock[MAX_NAME];
    /*private for the ticketclerk*/
    char ticketSum[MAX_NAME];
    /*private for concession clerk*/
    char food[2][MAX_NAME];
    /* amount in one group*/
    char amount[MAX_NAME];
    /* customer pay*/
    char payment[MAX_NAME];
    /* c0 is for customer in waiting line*/
    /* c1 is action between customer and employee*/
    char lineCondition[MAX_NAME];
    char msgCondition[MAX_NAME];
    char * employeeType;
} Employee;

typedef  struct
{
    int customerId;
    int groupId;
    int isTicketBuyer;
    int groupSize;
    /* how to find groupmate*/
    /*    Customer * customers;   /*Only head customers need this value*/
    int seatNumber;
} Customer;

int getIsBusy(Employee * employee)
{
    return getMV(employee->isBusy);
}
void setIsBusy(Employee * employee, int isBusy)
{
    setMV(employee->isBusy,isBusy);
}

int getIsBreak(Employee * employee)
{
    return getMV(employee->isBreak);
}
void setIsBreak(Employee * employee, int isBreak)
{
      setMV(employee->isBreak,isBreak);
}

int getWaitingSize(Employee * employee)
{
    return getMV(employee->waitingSize);
}

void subMV(char * name){
    int temp;
    temp=getMV(name);
    setMV(name,--temp);
}

void addMV(char * name){
    int temp;
    temp=getMV(name);
    setMV(name,++temp);
}
void addMVbyValue(char * name,int value){
    int temp;
    temp=getMV(name);
    setMV(name,value+temp);
}


void addWaitingSize(Employee * employee)
{
    int temp;
    temp=getMV(employee->waitingSize);
    setMV(employee->waitingSize,++temp);
}
void subWaitingSize(Employee * employee)
{
    int temp;
    temp=getMV(employee->waitingSize);
    setMV(employee->waitingSize,--temp);
}

int getAmount(Employee *employee)
{
    return getMV(employee->amount);
}
void setPayment(Employee *employee, int payment)
{
    setMV( employee->payment , payment);
}
void setTicketSum(Employee *employee, int ticketSum)
{
   setMV( employee->ticketSum , ticketSum);
}

void setGroupId(Employee *employee, int groupId)
{
    setMV(employee->groupId , groupId);
}
void setFood(Employee *employee, int index, int food)
{
    setMV(employee->food[index] , food);
}


int randNum;

int rand() {
    return (++randNum) % 10000;
}


char ticketClerkWorknoLock[MAX_NAME]="tcworknolock";
char ticketClerkWorkno[MAX_NAME]="tcworkno";

char numGroups[MAX_NAME]="numGroups";
char nextCustomerId[MAX_NAME]="nextCusID";
char  numCustomers[MAX_NAME] = "numCustomers";
char  numCustomersInGroup[MAX_GROUP][MAX_NAME];
char  headCustomerInGroup[MAX_GROUP][MAX_NAME];
char  curCustomerNumInGroup[MAX_GROUP][MAX_NAME];

char  groupAskForBathroom[MAX_GROUP][MAX_NAME];
char  groupNeedBathroom[MAX_GROUP][MAX_NAME];
char  numInGroupAskForBathroom[MAX_GROUP][MAX_NAME] ;

char  groupLeaveTheater[MAX_GROUP][MAX_NAME];

char cutomerNoLock[MAX_NAME]="cusNoLock";
char lBuyTickets[MAX_NAME]="lBuyTic";
char cNoTicketClerk[MAX_NAME]="cNoTC";

char tcNumber[MAX_NAME]="tcnumber";
char noTicketClerk[MAX_NAME] ="noTidClrk";
char cBreakTicketClerk[MAX_NAME]="cvBreakTC";
char breakTicketClerk[MAX_NAME]= "breakTicClrk";

char  ticketClerkAmount[MAX_TC][MAX_NAME] ;
char  ticketReceipt[MAX_GROUP][MAX_NAME];

char totalTicketSold[MAX_NAME]="totalTicSold";

char numGroupsRemaining[MAX_NAME]="numGroupsRemaining";
/*lock define*/
char lAmount[MAX_NAME]="lamount";
char lTicketSold[MAX_NAME]="lticsold";
/*end */

Customer cr[MAX_CR];
Employee tc[MAX_TC];
Employee cc[MAX_CC];
Employee tt[MAX_TT];
Employee mt;
Employee mr;
/* head customer and regular customer */
char  lGroup[MAX_GROUP][MAX_NAME];
char  cGroup[MAX_GROUP][MAX_NAME];
char   groupTicket[MAX_GROUP][MAX_NAME] ;
char  answerFood[MAX_GROUP][MAX_NAME] ;
char  groupFood[MAX_GROUP][MAX_NAME] ;
char  groupFoodSum[MAX_GROUP][2][MAX_NAME] ;
char  groupCheck[MAX_GROUP][MAX_NAME] ;
char  groupSeat[MAX_GROUP][MAX_NAME] ;
char  groupLeaveRoom[MAX_GROUP][MAX_NAME] ;
char  cGroupFood[MAX_GROUP][MAX_NAME];
char  groupAskForFood[MAX_GROUP][MAX_NAME] ;
char lFindSeats[MAX_NAME]="lfindseats";
char  seatLocation[MAX_GROUPSIZE][MAX_NAME];
char seatPos[MAX_NAME] = "seatpos";

char  answerBathroom[MAX_GROUP][MAX_NAME] ;
char  cGroupBathroom[MAX_GROUP][MAX_NAME] ;


/*define for concession clerk*/
char noConcessionClerk[MAX_NAME] ="noconcessclrk";
char cNoConcessionClerk[MAX_NAME]="cnoconcessclrk";
char cBreakConcessionClerk[MAX_NAME]="cbreakconclrk";
char  concessionClerkWorknoLock[MAX_NAME]="consworknolock";

char lBuyFood[MAX_NAME]="lBuyFood";
char ccNumber[MAX_NAME]="ccNumber";

char breakConcessionClerk[MAX_NAME]= "breakConcessionClerk";

char concessionClerkWorkNO[MAX_NAME]="concessionClerkWorkNO";
char  concessionClerkAmount[MAX_CC][MAX_NAME];

/*define for tickettaker*/
char * tickettakerWorkno="tickettakerWorkno";
char * cNoTicketTaker="cNoTicketTaker";
char * noTicketTaker = "noTicketTaker";
char * cBreakTicketTaker="cBreakTicketTaker";
char * breakTicketTaker = "breakTicketTaker";
char * stopTicketTaken="stopTicketTaken";
char  stopTicketTakenArr[MAX_TT][MAX_NAME];


char* ttNumber="ttNumber";
char * ticketTaken="ticketTaken";
char * totalTicketTaken="totalTicketTaken";



char lCheckTickets[MAX_NAME]="lCheckTickets";
char cTicketTaken[MAX_NAME]="cTicketTaken";
char lTicketTaken[MAX_NAME]="lTicketTaken";
char tickettakerWorknoLock[MAX_NAME]="tickettakerWorknoLock";

/*defien for the movie technician*/

char *    managerAskMTPlay="managerAskMTPlay";
char *    currentCustomerSeated="currentCustomerSeated";
char    seatState[MAX_SEAT][MAX_NAME];

char *    movieState="movieState";

char    lStopMovie[MAX_NAME]="lStopMovie";
char    lMovieState[MAX_NAME]="lMovieState";
char    managerAskMTplaylock[MAX_NAME]="managerAskMTplaylock";
char    currentCustomerSeatedlock[MAX_NAME]="currentCustomerSeatedlock";
char * currentCustomerAllSeated="currentCustomerAllSeated";
/*define for the use of manager*/
char   lCustomerLeft[MAX_NAME]="lCustomerLeft";
char   closeTheater[MAX_NAME]="closeTheater";

    
char *    customerLeft="customerLeft";
char *    totalAmount="totalAmount";

char * initLock="initLock";
char * initFlag="initFlag";


/**/

SpaceId exec(char *s){
    return Exec(s, Strlen(s));
}

int CreateLock(char *s)
{
    int result=0;
    Printf("try create lock %s\n",s);
    result=createLock(s, Strlen(s));
    if(-1!=result)
       /* Printf("create lock %s sucessfully result %d\n",s,result)*/;
    else 
        Printf("create lock %s failed\n",s);
    return result;
}

int AcquireLock(char *s){
    int result=0;
    Printf("try acquire lock %s\n",s);
    result=acquireLock(s, Strlen(s));
    if(-1!=result)
        Printf("acquire lock %s sucessfully\n",s);
    else 
        Printf("acquire lock %s failed\n",s);
    return result;
}

int ReleaseLock(char *s){
    int result=0;
    Printf("try release lock %s\n",s);
    result=releaseLock(s, Strlen(s));
    if(-1!=result)
        Printf("release lock %s sucessfully\n",s);
    else 
        Printf("release lock %s failed\n",s);
    return result;
}

int DeleteLock(char *s){
    int result=0;
    result=deleteLock(s, Strlen(s));
    if(-1!=result)
        Printf("delete lock %s sucessfully\n",s);
    else 
        Printf("delete lock %s failed\n",s);
    return result;
}

int CreateCV(char *s)
{
    int result=0;
    result=createCV(s, Strlen(s));
    if(-1!=result)
        /*Printf("create CV %s successfully result %d\n",s,result)*/;
    else 
        Printf("create CV %s failed\n",s);
    return result;
}

int WaitCV(char * lockname, char * cvname){
    int result=0;
     Printf("try wait CV lock %s cv %s \n",lockname,cvname);
    result=waitCV(lockname, Strlen(lockname), cvname, Strlen(cvname));
    if(-1!=result)
        Printf("wait CV lock %s cv %s sucessfully\n",lockname,cvname);
    else 
        Printf("wait CV lock %s cv %s failed\n",lockname,cvname);
    return result;
}

int SignalCV(char * lockname, char * cvname){
    int result=0;
     Printf("try signal CV lock %s cv %s \n",lockname,cvname);
    result=signalCV(lockname, Strlen(lockname), cvname, Strlen(cvname));
    if(-1!=result)
        Printf("signal CV lock %s cv %s sucessfully\n",lockname,cvname);
    else 
        Printf("signal CV lock %s cv %s failed\n",lockname,cvname);
    return result;
}

int BroadcastCV(char * lockname, char * cvname){
    int result=0;
     Printf("try broadcast CV lock %s cv %s \n",lockname,cvname);
    result=broadcastCV(lockname, Strlen(lockname), cvname, Strlen(cvname));
    if(-1!=result)
        Printf("broadcast CV lock %s cv %s sucessfully\n",lockname,cvname);
    else 
        Printf("broadcast CV lock %s cv %s failed\n",lockname,cvname);
    return result;
}

int DeleteCV(char * s){
    int result=0;
    result=deleteCV(s, Strlen(s));
    if(-1!=result)
        Printf("delete lock %s sucessfully\n",s);
    else 
        Printf("delete lock %s failed\n",s);
    return result;
}

int createMV(char * s){
    int result=0;
    result=rpcCreateMV(s, Strlen(s));
    if(-1!=result)
      /*  Printf("create mv %s successfully result %d\n",s,result);*/;
    else 
        Printf("create mv %s failed\n",s);
    return result;
}

int setMV(char * name, int value){
    int result=0;
        if(NULL==name){
        Printf("the name of mv could not be null\n");
        return -1;
    }
    Printf("try to set mv %s\n",name);
    result=rpcSetMV(name, Strlen(name),value);
    if(-1!=result)
        Printf("set mv %s to %d sucessfully\n",name,value);
    else 
        Printf("set mv %s to %d failed\n",name,value);
    return result;
}

int getMV(char * name){
    int result=0;

        if(NULL==name){
        Printf("the name of mv could not be null\n");
        return -1;
    }
    Printf("try to get mv %s\n",name);
    result=rpcGetMV(name, Strlen(name));
    Printf("get mv %s value %d sucessfully\n",name, result);
    return result;
}
/*code for customer*/

/************************************************
 *
 *  start for customer
 *
 ************************************************/
/************************************************
 *
 *  start for head customer
 *
 ************************************************/

int getInLine(char * lock, char * cNoClerk, char * count, char *noClerk, Employee employee[], Customer * customer )
{
    int i, j;
    int lineIndex = -1;
    int lineLen = -1;

    /* get in line lock to make sure no one can get in line at the same time */
    AcquireLock(lock);
    /* DEBUG('z', "\tGroup [%d] start find line\n", groupId) */;

    /* check every clerk */
    for (i = 0; i < getMV(count); ++i)
    {
        /*  if the clerk is not busy or not on break and no one wait in line, go to the line directly  */
        if (getIsBusy(&employee[i]) && !getIsBreak(&employee[i]) && getWaitingSize(&employee[i]) == 0)
        {
            lineIndex = i;
            break;
        }

        /*  if clerk is not on break, find a shortest line */
        if (!getIsBreak(&employee[i]) && (lineIndex == -1 || getWaitingSize(&employee[i]) < lineLen))
        {
            lineLen = getWaitingSize(&employee[i]);
            lineIndex = i;
        }
    }
    /* DEBUG('z', "\tGroup [%d] finish find line\n", groupId) */;

    if (lineIndex == -1)
    {
        /*  if all clerk are on break */
        /*  need to wait until the manager signal them */
        /* DEBUGINFO('c', "Customer [%d] in Group [%d] find noClerk concessionclerk, should wake up someone", customerId, groupId, employee[0].employeeType); */
        setMV(noClerk,1);
        Printf("Customer [%d] in Group [%d] is in the lobby.\n", customer->customerId, customer->groupId);
        WaitCV(lock, cNoClerk);
        Printf("Customer [%d] in Group [%d] is leaving the lobby.\n",  customer->customerId, customer->groupId);
        return lineIndex;

    }
    else
    {
        /* if head customer find the shortest line, waiting in line customer number add 1         */
        /* DEBUG('z', "\tbusy%d\n", getIsBusy(employee[lineIndex])?1:0) */;
        addWaitingSize(&employee[lineIndex]);
    }
    /* DEBUG('z', "\t%dline%d\n", lineIndex, getWaitingSize(employee[lineIndex])) */;
    /* DEBUGINFO('c', "\tCustomer [%d] in Group [%d] get in concessionclerk line [%d], length:%d, busy:%d\n", customerId, groupId, getEmployeeType(employee[lineIndex]), lineIndex, getWaitingSize(employee[lineIndex]), getIsBusy(employee[lineIndex])?1:0); */

    return lineIndex;
}


/* Head customer buy ticket for group member */
void buyTickets(int customerId)
{
    int lineIndex;
    int i;
    int groupId;
    int amount;
    Customer  * currentCR;
    Employee * clerk;
    currentCR=&cr[customerId];
    groupId = currentCR->groupId;
buyTickets:
    lineIndex = -1;

    /*AcquireLock(lBuyTickets); */
    /* Head customer try to get in shortest line */
    while (lineIndex == -1)
    {
        lineIndex = getInLine(lBuyTickets, cNoTicketClerk, tcNumber, noTicketClerk, tc, currentCR);
    }

    /*  get in which line */
    Printf("Customer [%d] in Group [%d] is getting in TicketClerk line [%d]\n",customerId,groupId,lineIndex);


    clerk = &tc[lineIndex];
    /*  if the clerk is busy serving other customer,wait for the clerk to wake them up  */
    /* DEBUGINFO('c', "Customer [%d] in Group [%d] get in %s line [%d], length:%d, busy:%d\n", customerId, groupId, getEmployeeType(clerk), lineIndex, getWaitingSize(clerk), getIsBusy(clerk)?1:0); */
    if (getIsBusy(clerk))
    {
        WaitCV(lBuyTickets, clerk->lineCondition);
    }
    Printf("Customer [%d] in Group [%d] is walking up to TicketClerk [%d] to buy [%d] tickets\n", currentCR->customerId, currentCR->groupId, lineIndex, currentCR->groupSize);

    /* DEBUGINFO('c', "Customer [%d] in group [%d] acquire lock [%s], owner %s", customerId, groupId, clerk.lock.getName(), clerk.lock.getOwnerThread()!=NULL?clerk.lock.getOwnerThread().getName():"NULL"); */


    /* DEBUGINFO('c', "Customer [%d] in Group [%d] sees TicketClerk [%d] break status [%d].\n",customerId,groupId,lineIndex, getIsBreak(clerk)?1:0); */
    /* waiting line number minus 1 */
    subWaitingSize(clerk);

    if (!getIsBreak(clerk))
    {
        /*  buy ticket :interact with TicketClerk */
        AcquireLock(clerk->lock);
        setIsBusy(clerk, true);
        ReleaseLock(lBuyTickets);
        /*  tell clerk tickets sum */
        setGroupId(clerk, currentCR->groupId);
        setTicketSum(clerk, currentCR->groupSize);
        SignalCV(clerk->lock, clerk->msgCondition);
        /* DEBUGINFO('c', "1 Customer [%d] in Group [%d] is walking up to TicketClerk [%d] to buy [%d] tickets\n",customerId,groupId,lineIndex,groupSize); */
        /*  wait for clerk to tell how much money */
        WaitCV(clerk->lock, clerk->msgCondition);
        /*  ask ticket clerk for total price */
        amount = getAmount(clerk);
        /*  pay money  */
        setPayment(clerk, amount);
        Printf("Customer [%d] in Group [%d] in TicketClerk line [%d] is paying [%d] for tickets\n",customerId,groupId,lineIndex,amount);
        /* DEBUGINFO('c', "2 Customer [%d] in Group [%d] in TicketClerk line [%d] is paying [%d] for tickets\n",customerId,groupId,lineIndex,amount); */
        /* to give the clerk money */
        SignalCV(clerk->lock, clerk->msgCondition);
        /*  wait to get tickets back */
        WaitCV(clerk->lock, clerk->msgCondition);
        /*  finish and leave */
        SignalCV(clerk->lock, clerk->msgCondition);
        /* DEBUGINFO('c', "3 Customer [%d] in Group [%d] is leaving TicketClerk [%d]\n",customerId,groupId,lineIndex); */
        Printf("Customer [%d] in Group [%d] is leaving TicketClerk[%d]\n",customerId,groupId,lineIndex);
    }
    else
    {
        /* if the clerk is on break,head customer need to start over and get another line */
        Printf("Customer [%d] in Group [%d] sees TicketClerk [%d] is on break.\n",customerId,groupId,lineIndex);
        ReleaseLock(lBuyTickets);
        goto buyTickets;
    }
    ReleaseLock(clerk->lock);
    /* DEBUGINFO('c', "Customer [%d] in group [%d] finish buy ticket from TicketClerk [%d]", customerId, groupId, lineIndex); */
}

/*  rand for food request */
int answerForFood(int food)
{
    return (rand()%4) > 0;
}

int countFood(int customerId, int groupId)
{
    int i;
    int temp;
    int temp1;
    AcquireLock(lGroup[groupId]);
    /*  if head customer self want food */
    for (i = 0; i < 2; ++i)
    {
        temp=getMV(groupFoodSum[groupId][i]);
        temp+= answerForFood(i);
        setMV(groupFoodSum[groupId][i],temp);
    }
    temp=getMV(answerFood[groupId]);
    temp++;
    setMV(answerFood[groupId],temp);
    /*  ask group mate if they want food */
    BroadcastCV(lGroup[groupId], cGroupFood[groupId]);
    /*  set monitor variable true */
    setMV(groupAskForFood[groupId],true);
    /*  wait for all the customer answer for food */
    temp=getMV(answerFood[groupId]);
    if (temp!= cr[customerId].groupSize)
    {
        WaitCV(lGroup[groupId], cGroupFood[groupId]);
    }
    ReleaseLock(lGroup[groupId]);
    temp=getMV(groupFoodSum[groupId][0]);
    temp1=getMV(groupFoodSum[groupId][1]);
    Printf("Customer [%d] in Group [%d] has [%d] popcorn and [%d] soda request from a group member\n",customerId,groupId,temp,temp1);

    /* if group member don't need any food */

    if (!temp&& !temp1)
    {
        setMV(groupFood[groupId] ,true);
        return false;
    }
    return true;
}

void buyFood(int customerId)
{
    int lineIndex;
    int i;
    int groupId;
    int amount;
    Customer  * currentCR;
    Employee * clerk;
    currentCR=&cr[customerId];
    groupId = currentCR->groupId;
buyFood:
    lineIndex = -1;
    /*AcquireLock(lBuyFood); */
    /* Head customer try to get in shortest line */
    while (lineIndex == -1)
    {
        lineIndex = getInLine(lBuyFood, cNoConcessionClerk, ccNumber, noConcessionClerk, cc, currentCR);
    }
    /* DEBUGINFO('c', "Customer [%d] in group [%d] get in ConcessionClerk [%d]", customerId, groupId, lineIndex) */;
    Printf("Customer [%d] in Group [%d] is getting in ConcessionClerk line [%d]\n",customerId,groupId,lineIndex);

    clerk = &cc[lineIndex];

    /*  if the clerk is busy serving other customer,wait for the clerk to wake them up  */
    if (getIsBusy(clerk))
    {
        WaitCV(lBuyFood, clerk->lineCondition);
        /* DEBUGINFO('c', "Customer [%d] in group [%d] is wake up to goto ConcessionClerk [%d]", customerId, groupId, lineIndex) */;
    }
    /* DEBUGINFO('c', "Customer [%d] in group [%d] is walking up to ConcessionClerk [%d]", customerId, groupId, lineIndex) */;
    Printf("Customer [%d] in Group [%d] is walking up to ConcessionClerk [%d] to buy [%d] popcorn and [%d] soda.\n",customerId,groupId,lineIndex,getMV( groupFoodSum[groupId][0]),getMV(groupFoodSum[groupId][1]));

    /* DEBUGINFO('c', "Customer [%d] in group [%d] acquire lock [%s], owner %s", customerId, groupId, clerk->lock->getName(), clerk->lock->getOwnerThread()!=NULL?clerk->lock->getOwnerThread()->getName():"NULL") */;
    /* DEBUGINFO('c', "Customer [%d] in group [%d] acquired lock [%d], owner %s", customerId, groupId, clerk->lock->getName(), clerk->lock->getOwnerThread()!=NULL?clerk->lock->getOwnerThread()->getName():"NULL") */;

    /* waiting line number minus 1     */
    subWaitingSize(clerk);

    if (!getIsBreak(clerk))
    {
        /* buyfood: interact with ConcessionClerk  */
        AcquireLock(clerk->lock);
        setIsBusy(clerk, true);
        ReleaseLock(lBuyFood);

        /*  tell clerk popcorn sum and soda sum */
        setGroupId(clerk, groupId);
        /* DEBUGINFO('c', "Customer [%d] in group [%d] interact with ConcessionClerk [%d]", customerId, groupId, lineIndex) */;
        for (i = 0; i < 2; ++i)
        {
            setFood(clerk, i, getMV(groupFoodSum[groupId][i]));
            SignalCV(clerk->lock, clerk->msgCondition);
            /*  wait for acknowledgement and amount */
            WaitCV(clerk->lock, clerk->msgCondition);
        }


        /* DEBUGINFO('c', "Customer [%d] in group [%d] is paying to ConcessionClerk [%d]", customerId, groupId, lineIndex) */;
        /*  give money */
        amount = getAmount(clerk);
        setPayment(clerk, amount);
        Printf("Customer [%d] in Group [%d] in ConcessionClerk line [%d] is paying [%d] for food\n",customerId,groupId,lineIndex,amount);
        SignalCV(clerk->lock, clerk->msgCondition);
        /* wait for clerk to acknowledge money  */
        WaitCV(clerk->lock, clerk->msgCondition);
        /*  customer leave, get next customer */
        SignalCV(clerk->lock, clerk->msgCondition);

        /* DEBUGINFO('c', "Customer [%d] in group [%d] is leaving ConcessionClerk [%d]", customerId, groupId, lineIndex) */;
        Printf("Customer [%d] in Group [%d] is leaving ConcessionClerk[%d]\n",customerId,groupId,lineIndex);
        ReleaseLock(clerk->lock);
    }
    else
    {
        /* if the clerk is on break,head customer need to start over and get another line */
        Printf("Customer [%d] in Group [%d] sees ConcessionClerk [%d] is on break.\n",customerId,groupId,lineIndex);
        /* DEBUGINFO('c', "Customer [%d] in group [%d] sees ConcessionClerk [%d] on break", customerId, groupId, lineIndex) */;
        /* subWaitingSize(clerk); */
        /*  for race condition of waiting size */
        ReleaseLock(lBuyFood);
        goto buyFood;
    }
}
/* Head customer go to ticket taker and check ticket */
void checkTickets(int customerId)
{
    int lineIndex;
    int i;
    int groupId;
    int amount;
    int temp;
    Customer  * currentCR;
    Employee * clerk;
    currentCR=&cr[customerId];
    groupId = currentCR->groupId;
checkTickets:
    lineIndex = -1;
    /* Head customer try to get in shortest line */
    while (lineIndex == -1)
    {
        lineIndex = getInLine(lCheckTickets, cNoTicketTaker, ttNumber, noTicketTaker, tt, currentCR);
    }

    Printf("Customer [%d] in Group [%d] is getting in TicketTaker line [%d]\n",customerId,groupId,lineIndex);
    clerk = &tt[lineIndex];
    /* DEBUGINFO('c', "Customer [%d] in group [%d] get in %s [%d]", customerId, groupId, clerk->employeeType, lineIndex) */;

    /*  if the clerk is busy serving other customer,wait for the clerk to wake them up  */
    if (getIsBusy(clerk))
    {
        /* DEBUGINFO('c', "Customer [%d] in group [%d] wait for TicketTaker [%d]", customerId, groupId, lineIndex) */;
        WaitCV(lCheckTickets, clerk->lineCondition);

    }
    /* DEBUGINFO('c', "Customer [%d] in group [%d] acquire lTicketTaken with %s [%d], lTicketTaken's owner is: %s", customerId, groupId, clerk->employeeType, lineIndex, lTicketTaken->getOwnerThread()==NULL?"NULL":lTicketTaken->getOwnerThread()->getName()) */;
    /* ticket taken : interact with ticket taker  */
    /* waiting line number minus 1     */
    subWaitingSize(clerk);

    /* DEBUGINFO('c', "Customer [%d] in Group [%d] is walking up to %s [%d] to give [%d] tickets.\n",customerId,groupId, clerk->employeeType, lineIndex, ticketReceipt[groupId]) */;
    Printf("Customer [%d] in Group [%d] is walking up to TicketTaker [%d] to give [%d] tickets.\n",customerId,groupId,lineIndex, currentCR->groupSize);

    /*  ticker take: interact with TicketTaker  */
    if (!getIsBreak(clerk) )
    {
        AcquireLock(clerk->lock);
        /* DEBUGINFO('c', "Customer [%d] in group [%d] get lock with %s [%d]", customerId, groupId, clerk->employeeType, lineIndex) */;
        setIsBusy(clerk, true);
        /* DEBUGINFO('c', "Customer [%d] in group [%d] wait %s [%d]", customerId, groupId, clerk->employeeType, lineIndex) */;
        ReleaseLock(lCheckTickets);
        /* DEBUGINFO('c', "Customer [%d] in group [%d] wait %s [%d]", customerId, groupId, clerk->employeeType, lineIndex) */;
        setGroupId(clerk, groupId);
        /* DEBUGINFO('c', "Customer [%d] in group [%d] wait %s [%d]", customerId, groupId, clerk->employeeType, lineIndex) */;
        /*  give ticket taker ticket */
        setTicketSum(clerk, currentCR->groupSize);
        /* DEBUGINFO('c', "Customer [%d] in group [%d] wait %s [%d]", customerId, groupId, clerk->employeeType, lineIndex) */;
        SignalCV(clerk->lock, clerk->msgCondition);
        /* DEBUGINFO('c', "Customer [%d] in group [%d] wait %s [%d]", customerId, groupId, clerk->employeeType, lineIndex) */;
        /*  wait for ticket taker to check ticket */
        WaitCV(clerk->lock, clerk->msgCondition);
        /* DEBUGINFO('c', "Customer [%d] in group [%d] get lock with %s [%d]", customerId, groupId, clerk->employeeType, lineIndex) */;

        /*  if ticket taker foound the seats in the theater room are just not enough for the group, ticket taker stop take ticket */
        /*AcquireLock(lTicketTaken); */
        
        if (getMV(stopTicketTakenArr[lineIndex]))
        {
            /*  ask all group to go back lobby and wait for recheck the tickets */
            ReleaseLock(clerk->lock);
            Printf("Customer [%d] in Group [%d] sees TicketTaker [%d] is no longer taking tickets. Going to the lobby2.\n", customerId, groupId, lineIndex);
            Printf("Customer [%d] in Group [%d] is in the lobby.\n", customerId, groupId);
            /* DEBUGINFO('c', "Customer [%d] in group [%d] wait to retake ticket", customerId, groupId, lineIndex) */;
            AcquireLock(lTicketTaken);
            temp=getMV(stopTicketTaken);
            if (temp)
            {
                WaitCV(lTicketTaken, cTicketTaken);
            }
            Printf("Customer [%d] in Group [%d] is leaving the lobby.\n",  customerId, groupId);
            /* DEBUGINFO('c', "Customer [%d] in group [%d] get lock with ticket taker [%d]", customerId, groupId, lineIndex) */;
            ReleaseLock(lTicketTaken);
            goto checkTickets;
        }
        /* DEBUGINFO('c', "Customer [%d] in group [%d] is leaving %s [%d] get into room", customerId, groupId, clerk->employeeType, lineIndex) */;
        /*  get into room */
        SignalCV(clerk->lock, clerk->msgCondition);
        Printf("Customer [%d] in Group [%d] is leaving TicketTaker[%d]\n",customerId,groupId,lineIndex);
        /* DEBUGINFO('c', "Customer [%d] in group [%d] is leaving %s [%d] after get into room", customerId, groupId, clerk->employeeType, lineIndex) */;
    }
    else
    {
        /* if the clerk is on break,head customer need to start over and get another line */
        /* DEBUGINFO('c', "Customer [%d] in group [%d] sees TicketTaker [%d] is on break.", customerId, groupId, lineIndex) */;
        Printf("Customer [%d] in Group [%d] sees TicketTaker [%d] is on break.\n",customerId,groupId,lineIndex);
        AcquireLock(lCheckTickets);
        /*  for race condition of waiting size */
        ReleaseLock(lCheckTickets);
        goto checkTickets;
    }
    /* DEBUGINFO('c', "Customer [%d] in group [%d] is leaving %s [%d] b get into room", customerId, groupId, clerk->employeeType, lineIndex) */;
    ReleaseLock(clerk->lock);
    /* DEBUGINFO('c', "Customer [%d] in group [%d] is leaving %s [%d] c get into room", customerId, groupId, clerk->employeeType, lineIndex) */;
}

/* Head customer find available seats */
void getSeats(int Size){
    int i=0;
    int temp;
    int j=0;
    for(i=0;i<MAX_SEAT;i++){
        temp=getMV(seatState[i]);
        if(false==temp)
            break;
    }
    for(j=0;j<Size;j++)
   {
        setMV(seatLocation[j],i++);        
    }
}
/*  Head customer get seat for the group */
void arrangeSeats(int customerId, int groupId) {
    int temp;
    int temp1;
    /*  lock the seats and make sure no other head customer is going to arrange seats  */
    AcquireLock(lFindSeats);
    /* DEBUGINFO('c', "SeatAvailable group size[%d]\n",groupSize) */;  

    /* get seat number  */
    getSeats(getMV(numCustomersInGroup[groupId]));
    setMV(seatPos , 0);	
    temp1=getMV(seatLocation[0]);
    Printf("Customer [%d] in Group [%d] has found the following seat: row [%d] and seat [%d]\n",customerId,groupId,(temp1/MAX_ROW),temp1%MAX_COL);  
  setMV(seatState[temp1],true);
     setMV(seatPos , 1);
    AcquireLock(lGroup[groupId]);
    /* DEBUGINFO('c', "Customer [%d] in Group [%d] arrange seat %d", customerId,groupId,SeatLocation[0]) */;
    
    /*  tell other group member the seat number  */
    BroadcastCV(lGroup[groupId], cGroup[groupId]);
    setMV(groupSeat[groupId] , true);
    temp=getMV(seatPos);
    if (temp != cr[customerId].groupSize) {
    /* DEBUGINFO('c', "Customer [%d] in Group [%d] arrange seat %d", customerId,groupId,SeatLocation[i]) */;
        WaitCV(lGroup[groupId], cGroup[groupId]);
    }
    ReleaseLock(lGroup[groupId]);
    ReleaseLock(lFindSeats);      

}

/* customers wait fot movie to start */
void watchMovie(int customerId, int groupId){
    int temp;
    Employee * currentMT = &mt;
    AcquireLock(currentCustomerSeatedlock);
    addMV(currentCustomerSeated);
    /*Printf("++currentCustomerSeated %d , ticketTaken %d\n", currentCustomerSeated, ticketTaken); */
    AcquireLock(lStopMovie);
    ReleaseLock(currentCustomerSeatedlock);
    /* Customers are checkd by Movie Techinician if they were seated */
    /* DEBUGINFO('c', "Customer [%d] in group [%d] is sitting in a theater room seat.", customerId, groupId) */;
    Printf("Customer [%d] in group [%d] is sitting in a theater room seat.\n",customerId,groupId);
    /* watching movie and wait Movie Techinician to wake them up */
    WaitCV(lStopMovie,mt.msgCondition);
    ReleaseLock(lStopMovie);
    AcquireLock(currentCustomerSeatedlock);
    subMV(currentCustomerSeated);
    temp=getMV(currentCustomerSeated);
    if (!temp) {
        SignalCV(currentCustomerSeatedlock, mt.lineCondition);
    }
    ReleaseLock(currentCustomerSeatedlock);
    /* DEBUGINFO('c', "Customer [%d] in group [%d] end acquire lStopMovie, lStopMovie's owner : %s", customerId,groupId, lStopMovie->getOwnerThread() == NULL? "NULL": lStopMovie->getOwnerThread()->getName()) */;
    /* DEBUGINFO('c', "Customer [%d] in group [%d] is watching movie and wait up by Movie Techinician.", customerId, groupId) */;
}

void proceed(int customerId, int groupId, char *flag)
{
    /* DEBUGINFO('c', "Customer [%d] in Group [%d] proceed to next.\n",customerId,groupId) */;
    /* DEBUGINFO('c', "Customer [%d] in Group [%d] proceed to next.\n",customerId,groupId) */;
    /*  tell group to go */
    /* DEBUGINFO('c', "Customer [%d] in Group [%d] acquire lGroup[%d], lGroup[]'s owner is %s ", customerId, groupId, groupId, lGroup[groupId]->getOwnerThread() == NULL? "NULL" : lGroup[groupId]->getOwnerThread()->getName()) */;
    AcquireLock(lGroup[groupId]);
    BroadcastCV(lGroup[groupId], cGroup[groupId]);
    Printf("HeadCustomer [%d] of group [%d] has told the group to proceed.\n", customerId, groupId);
    /*  monitor variables */
    setMV(flag, true);
    ReleaseLock(lGroup[groupId]);
}
int answerForBathroom() {
    int chance = rand()%100;
    if(chance<=25){
        return true;
    }
    return false;
}


void RT1LO1(){
    int result;
    Printf("rpctest 5 or 6:RT2LO1 is going to login on \n");  
    result=rpcLoginOn(1234);
    if(-1!=result)
        Printf("rpctest 5 or 6:login successed\n");
    else
        Printf("rpctest 5 or 6:login failed\n");
}


void initRPCVars()
{
    int result;
    int i;
    CreateLock(ticketClerkWorknoLock);
    createMV(ticketClerkWorkno);
 
    CreateLock(lCustomerLeft);
    createMV(closeTheater);

/*mv for customers*/
    createMV(numGroups);
    createMV(nextCustomerId);
    for (i = 0; i < MAX_GROUP; ++i)
    {
        Strcpy(lGroup[i],"___lGroup");
        number(lGroup[i],i,10,0);
        CreateLock(lGroup[i] );

        Strcpy(ticketReceipt[i],"___ticketReceipt");
        number(ticketReceipt[i],i,10,0);

        createMV(ticketReceipt[i]); 
		 
       Strcpy(headCustomerInGroup[i] , "___headCustomerInGroup");
       number(headCustomerInGroup[i] ,i,10,0);
       result=createMV(headCustomerInGroup[i]);
       if(ALREADY_HAVE!=result)
        setMV(headCustomerInGroup[i],-1);

        Strcpy(cGroup[i],"___cGroup");
        number(cGroup[i],i,10,0);
        CreateCV(cGroup[i]);

        
        Strcpy(cGroupFood[i] , "___cGroupFood");
       number(cGroupFood[i],i,10,0);
        CreateCV(cGroupFood[i]);

        Strcpy(groupFood[i] , "___groupFood");
       number(groupFood[i],i,10,0);
        createMV(groupFood[i]);

                Strcpy(groupCheck[i] , "___groupCheck");
       number(groupCheck[i],i,10,0);
        createMV(groupCheck[i]);
        
        
       Strcpy( cGroupBathroom[i],"___cGroupBathroom");
        number(cGroupBathroom[i],i,10,0);
        CreateCV( cGroupBathroom[i]);
        
        Strcpy(answerBathroom[i],"___answerBathroom");
        number(answerBathroom[i],i,10,0);
        createMV(answerBathroom[i]);
        
        Strcpy(numCustomersInGroup[i],"___numCustomersInGroup");
        number(numCustomersInGroup[i],i,10,0);
        createMV(numCustomersInGroup[i]);

        Strcpy(groupAskForFood[i],"___groupAskForFood");
        number(groupAskForFood[i],i,10,0);
        createMV(groupAskForFood[i]);

       Strcpy( groupTicket[i],"___groupTicket");
        number(groupTicket[i],i,10,0);
        createMV(groupTicket[i]);

        Strcpy(answerFood[i],"___answerFood");
        number(answerFood[i],i,10,0);
        createMV(answerFood[i]);

        Strcpy(groupCheck[i],"___groupCheck");
        number(groupCheck[i],i,10,0);
        createMV(groupCheck[i]);

        Strcpy(groupSeat[i],"___groupSeat");
        number(groupSeat[i],i,10,0);
        createMV(groupSeat[i]);

        Strcpy(groupLeaveRoom[i],"___groupLeaveRoom");
        number(groupLeaveRoom[i],i,10,0);
        createMV(groupLeaveRoom[i]);

        Strcpy(groupLeaveTheater[i],"___groupLeaveTheater");
        number(groupLeaveTheater[i],i,10,0);
        createMV(groupLeaveTheater[i]);

       Strcpy( groupAskForBathroom[i],"___groupAskForBathroom");
       number(groupAskForBathroom[i],i,10,0);
        createMV(groupAskForBathroom[i]);

        Strcpy(numInGroupAskForBathroom[i],"___numInGroupAskForBathroom");
        number(numInGroupAskForBathroom[i],i,10,0);
        createMV(numInGroupAskForBathroom[i]);

        Strcpy(curCustomerNumInGroup[i],"___curCustomerNumInGroup");
        number(curCustomerNumInGroup[i],i,10,0);
        createMV(curCustomerNumInGroup[i]);

        Strcpy(groupFoodSum[i][0],"___groupFood0Sum");
       number(groupFoodSum[i][0],i,10,0);
        createMV(groupFoodSum[i][0]);

        Strcpy(groupFoodSum[i][1],"___groupFood1Sum");
        number(groupFoodSum[i][1],i,10,0);
        createMV(groupFoodSum[i][1]);

        
    }

/*create mv*/
    createMV(concessionClerkWorkNO);
    createMV(breakConcessionClerk);
    createMV(seatPos);
    createMV(ticketClerkWorkno);
    createMV(breakTicketClerk);
    createMV(stopTicketTaken);
    createMV(ticketTaken);
    createMV(currentCustomerSeated);
    createMV(customerLeft);
    createMV(tcNumber);
    createMV(ccNumber);
    createMV(totalAmount);
    createMV(totalTicketSold);
    createMV(totalTicketTaken);
    createMV(managerAskMTPlay);
    createMV(tickettakerWorkno);
    createMV(breakTicketTaker);
    createMV(numCustomers);

/*end create mv*/
     CreateLock(cutomerNoLock);
     CreateLock(lBuyTickets);
     CreateCV(cNoTicketClerk);
     CreateCV(cBreakTicketClerk);
      CreateCV(cNoConcessionClerk);
     CreateCV(cBreakConcessionClerk);
     CreateCV(cNoTicketTaker);
      CreateCV(cBreakTicketTaker);

    createMV(noTicketClerk);
    createMV(noConcessionClerk);
    createMV(noTicketTaker);
    createMV(totalTicketSold);
    createMV(ttNumber);
    createMV(numGroupsRemaining);
    /*lock define*/
    CreateLock(lAmount);
    CreateLock(lTicketSold);
    /*end */
    for (i = 0; i < MAX_TC; ++i)
    {
        Strcpy(tc[i].lock,"___tclock");
        number(tc[i].lock,i,10,0);
        CreateLock(tc[i].lock);
        
/*        Strcpy(ticketReceipt[i],"___ticketReceipt");
        number(ticketReceipt[i],i,10,0);
        createMV(ticketReceipt[i]);      
*/
        Strcpy(tc[i].lineCondition,"___tclineCondition");
        number(tc[i].lineCondition,i,10,0);
        CreateCV(tc[i].lineCondition);

        Strcpy(tc[i].msgCondition,"___tcmsgCondition");
        number(tc[i].msgCondition,i,10,0);
        CreateCV(tc[i].msgCondition);
        /*Printf("tc[i].lock %d, tc[i].lineCondition %d, tc[i].msgCondition %d\n", tc[i].lock, tc[i].lineCondition, tc[i].msgCondition); */

        Strcpy(tc[i].ticketSum,"___tcticketSum");
        number(tc[i].ticketSum,i,10,0);
        createMV(tc[i].ticketSum);

        Strcpy(tc[i].groupId,"___tcgroupId");
        number(tc[i].groupId,i,10,0);
        createMV(tc[i].groupId);

       Strcpy( tc[i].isBusy,"___tcisBusy");
        number(tc[i].isBusy,i,10,0);
        result=createMV(tc[i].isBusy);
        if(ALREADY_HAVE!=result)
        setMV(tc[i].isBusy,true);
        
        Strcpy(tc[i].isBreak,"___tcisBreak");
        number(tc[i].isBreak,i,10,0);
        createMV(tc[i].isBreak);

        Strcpy(tc[i].waitingSize,"___tcwaitingSize");
        number(tc[i].waitingSize,i,10,0);
        createMV(tc[i].waitingSize);
        
        Strcpy(tc[i].amount,"___tcamount");
        number(tc[i].amount,i,10,0);
        createMV(tc[i].amount);

        Strcpy(tc[i].payment,"___tcpayment");
        number(tc[i].payment,i,10,0);
        createMV(tc[i].payment);

        Strcpy(ticketClerkAmount[i],"___ticketClerkAmount");
        number(ticketClerkAmount[i],i,10,0);
        createMV(ticketClerkAmount[i]);

        tc[i].employeeType="___ticketclerk";
    }
    /*init for the concession clerk*/
    CreateLock(concessionClerkWorknoLock);
    CreateLock(lBuyFood);
    
    for (i = 0; i < MAX_CC; ++i)
    {
        Strcpy(cc[i].lock,"___cclock");
        number(cc[i].lock,i,10,0);
        CreateLock(cc[i].lock);

        Strcpy(cc[i].lineCondition,"___cclineCondition");
        number(cc[i].lineCondition,i,10,0);
        CreateCV(cc[i].lineCondition);
        
        Strcpy(cc[i].msgCondition,"___ccmsgCondition");
        number(cc[i].msgCondition,i,10,0);
        CreateCV(cc[i].msgCondition);

        Strcpy(cc[i].groupId,"___ccgroupId");
        number(cc[i].groupId,i,10,0);
        createMV(cc[i].groupId);

        
        /*Printf("cc[i].lock %d, cc[i].lineCondition %d, cc[i].msgCondition %d\n", cc[i].lock, cc[i].lineCondition, cc[i].msgCondition); */
        Strcpy(cc[i].ticketSum,"___ccticketSum");
        number(cc[i].ticketSum,i,10,0);
        createMV(cc[i].ticketSum);

        Strcpy(cc[i].isBusy,"___ccisBusy");
        number(cc[i].isBusy,i,10,0);
        result=createMV(cc[i].isBusy);
        if(ALREADY_HAVE!=result)
        setMV(cc[i].isBusy,true);
        
        Strcpy(cc[i].isBreak,"___ccisBreak");
        number(cc[i].isBreak,i,10,0);
        createMV(cc[i].isBreak);

        Strcpy(cc[i].waitingSize,"___ccwaitingSize");
        number(cc[i].waitingSize,i,10,0);
        createMV(cc[i].waitingSize);
        
        Strcpy(cc[i].amount,"___ccamount");
        number(cc[i].amount,i,10,0);
        createMV(cc[i].amount);

       Strcpy( cc[i].payment,"___ccpayment");
        number(cc[i].payment,i,10,0);
        createMV(cc[i].payment);

        Strcpy(cc[i].food[0],"___ccfood[0]");
        number(cc[i].food[0],i,10,0);
        createMV(cc[i].food[0]);
        
        Strcpy(cc[i].food[1],"___ccfood[1]");
        number(cc[i].food[1],i,10,0);
        createMV(cc[i].food[1]);

        Strcpy(concessionClerkAmount[i],"___concessionClerkAmount");
        number(concessionClerkAmount[i],i,10,0);
        createMV(concessionClerkAmount[i]);

        cc[i].employeeType="___concessionclerk";
    }
    /*init ticket taker*/
    CreateLock(lCheckTickets);
    CreateCV(cTicketTaken);
    CreateLock(lTicketTaken);
    CreateLock(tickettakerWorknoLock);
    for (i = 0; i < MAX_TT; ++i)
    {
        Strcpy(tt[i].lock,"___ttlock");
        number(tt[i].lock,i,10,0);
        CreateLock(tt[i].lock);

        Strcpy(tt[i].lineCondition,"___ttlineCondition");
        number(tt[i].lineCondition,i,10,0);
        CreateCV(tt[i].lineCondition);
        
        Strcpy(tt[i].msgCondition,"___ttmsgCondition");
        number(tt[i].msgCondition,i,10,0);
        CreateCV(tt[i].msgCondition);

        Strcpy(tt[i].groupId,"___ttgroupId");
        number(tt[i].groupId,i,10,0);
        createMV(tt[i].groupId);

        
        /*Printf("tt[i].lock %d, tt[i].lineCondition %d, tt[i].msgCondition %d\n", tt[i].lock, tt[i].lineCondition, tt[i].msgCondition); */
        Strcpy(tt[i].ticketSum,"___ttticketSum");
        number(tt[i].ticketSum,i,10,0);
        createMV(tt[i].ticketSum);

        Strcpy(stopTicketTakenArr[i],"___stopTicketTakenArr");
        number(stopTicketTakenArr[i],i,10,0);
        createMV(stopTicketTakenArr[i]);


        Strcpy(tt[i].isBusy,"___ttisBusy");
        number(tt[i].isBusy,i,10,0);
        result=createMV(tt[i].isBusy);
        if(ALREADY_HAVE!=result)
        setMV(tt[i].isBusy,true);
        
        Strcpy(tt[i].isBreak,"___ttisBreak");
        number(tt[i].isBreak,i,10,0);
        createMV(tt[i].isBreak);

        Strcpy(tt[i].waitingSize,"___ttwaitingSize");
        number(tt[i].waitingSize,i,10,0);
        createMV(tt[i].waitingSize);
        
        Strcpy(tt[i].amount,"___ttamount");
        number(tt[i].amount,i,10,0);
        createMV(tt[i].amount);

        Strcpy(tt[i].payment,"___ttpayment");
        number(tt[i].payment,i,10,0);
        createMV(tt[i].payment);

        tt[i].employeeType="___tickettaker";
    }
    for(i=0;i<MAX_SEAT;i++){
        Strcpy(seatState[i],"___seatState");
        number(seatState[i],i,10,0);
        createMV(seatState[i]);
    }

    for(i=0;i<MAX_GROUPSIZE;i++){
        Strcpy(seatLocation[i],"___seatLocation");
        number(seatLocation[i],i,10,0);
        createMV(seatLocation[i]);
    }
     CreateLock(lFindSeats);
    /*int for the movie technician*/
    CreateLock(lStopMovie);
    CreateLock(lMovieState);

    result=createMV(movieState);
   if(ALREADY_HAVE!=result)
    setMV(movieState,1);

    CreateLock(managerAskMTplaylock);
    CreateLock(currentCustomerSeatedlock);
    
    Strcpy(mt.lock,"mtlock");
    CreateLock(mt.lock);
    
    Strcpy(mt.lineCondition,"mtlineCondition");
    CreateCV(mt.lineCondition);

    
    Strcpy(mt.msgCondition,"mtmsgCondition");
    CreateCV(mt.msgCondition);

    /*Printf("mt.lock %d, mt.lineCondition %d, mt.msgCondition %d\n", mt.lock, mt.lineCondition, mt.msgCondition); */
    Strcpy(mt.ticketSum,"mtticketSum");
    createMV(mt.ticketSum);
    
   Strcpy( mt.isBusy,"mtisBusy");
   result= createMV(mt.isBusy);
   if(ALREADY_HAVE!=result)
    setMV(mt.isBusy,true);
    
    Strcpy(mt.isBreak,"mtisBreak");
    createMV(mt.isBreak);

            Strcpy(mt.groupId,"___mtgroupId");
        createMV(mt.groupId);
    
    Strcpy(mt.waitingSize,"mtwaitingSize");
    createMV(mt.waitingSize);
    
    Strcpy(mt.amount,"mtamount");
    createMV(mt.amount);
    
    Strcpy(mt.payment,"mtpayment");
    createMV(mt.payment);

    Strcpy(mr.msgCondition,"mrmsgCondition");
    CreateCV(mr.msgCondition);

    mr.employeeType="manager";

}


void initTheater1()
{
    int i=0;
    int inputValue = 0;
    RT1LO1();

    initRPCVars();

    setMV(numCustomers , NUM_GROUP*3);
    setMV(customerLeft, NUM_GROUP*3);
    setMV(tcNumber, 3);
    setMV(ccNumber ,3);
    setMV(ttNumber, 3);
    setMV(numGroups,NUM_GROUP);
    for (i = 0;i < NUM_GROUP; ++i) {
        setMV(numCustomersInGroup[i] ,3);
    }
}


void initRPCVars1()
{
    int result;
    int i;


    for (i = 0; i < MAX_GROUP; ++i)
    {
        Strcpy(lGroup[i],"___lGroup");
        number(lGroup[i],i,10,0);

        Strcpy(ticketReceipt[i],"___ticketReceipt");
        number(ticketReceipt[i],i,10,0);
         
       Strcpy(headCustomerInGroup[i] , "___headCustomerInGroup");
       number(headCustomerInGroup[i] ,i,10,0);

        Strcpy(cGroup[i],"___cGroup");
        number(cGroup[i],i,10,0);

        
        Strcpy(cGroupFood[i] , "___cGroupFood");
       number(cGroupFood[i],i,10,0);
        Strcpy(groupFood[i] , "___groupFood");
       number(groupFood[i],i,10,0);

       Strcpy(groupCheck[i] , "___groupCheck");
       number(groupCheck[i],i,10,0);
        
       Strcpy( cGroupBathroom[i],"___cGroupBathroom");
        number(cGroupBathroom[i],i,10,0);
        
        Strcpy(answerBathroom[i],"___answerBathroom");
        number(answerBathroom[i],i,10,0);
        
        Strcpy(numCustomersInGroup[i],"___numCustomersInGroup");
        number(numCustomersInGroup[i],i,10,0);

        Strcpy(groupAskForFood[i],"___groupAskForFood");
        number(groupAskForFood[i],i,10,0);
   

       Strcpy( groupTicket[i],"___groupTicket");
        number(groupTicket[i],i,10,0);


        Strcpy(answerFood[i],"___answerFood");
        number(answerFood[i],i,10,0);
        
        Strcpy(groupCheck[i],"___groupCheck");
        number(groupCheck[i],i,10,0);


        Strcpy(groupSeat[i],"___groupSeat");
        number(groupSeat[i],i,10,0);
  

        Strcpy(groupLeaveRoom[i],"___groupLeaveRoom");
        number(groupLeaveRoom[i],i,10,0);

        Strcpy(groupLeaveTheater[i],"___groupLeaveTheater");
        number(groupLeaveTheater[i],i,10,0);

       Strcpy( groupAskForBathroom[i],"___groupAskForBathroom");
       number(groupAskForBathroom[i],i,10,0);


        Strcpy(numInGroupAskForBathroom[i],"___numInGroupAskForBathroom");
        number(numInGroupAskForBathroom[i],i,10,0);

        Strcpy(curCustomerNumInGroup[i],"___curCustomerNumInGroup");
        number(curCustomerNumInGroup[i],i,10,0);
        
        Strcpy(groupFoodSum[i][0],"___groupFood0Sum");
       number(groupFoodSum[i][0],i,10,0);

        Strcpy(groupFoodSum[i][1],"___groupFood1Sum");
        number(groupFoodSum[i][1],i,10,0);

        
    }

    /*end */
    for (i = 0; i < MAX_TC; ++i)
    {
        Strcpy(tc[i].lock,"___tclock");
        number(tc[i].lock,i,10,0);

 

        Strcpy(tc[i].lineCondition,"___tclineCondition");
        number(tc[i].lineCondition,i,10,0);

        Strcpy(tc[i].msgCondition,"___tcmsgCondition");
        number(tc[i].msgCondition,i,10,0);
        /*Printf("tc[i].lock %d, tc[i].lineCondition %d, tc[i].msgCondition %d\n", tc[i].lock, tc[i].lineCondition, tc[i].msgCondition); */

        Strcpy(tc[i].ticketSum,"___tcticketSum");
        number(tc[i].ticketSum,i,10,0);

        Strcpy(tc[i].groupId,"___tcgroupId");
        number(tc[i].groupId,i,10,0);

       Strcpy( tc[i].isBusy,"___tcisBusy");
        number(tc[i].isBusy,i,10,0);

        Strcpy(tc[i].isBreak,"___tcisBreak");
        number(tc[i].isBreak,i,10,0);

        Strcpy(tc[i].waitingSize,"___tcwaitingSize");
        number(tc[i].waitingSize,i,10,0);
        
        Strcpy(tc[i].amount,"___tcamount");
        number(tc[i].amount,i,10,0);

        Strcpy(tc[i].payment,"___tcpayment");
        number(tc[i].payment,i,10,0);

        Strcpy(ticketClerkAmount[i],"___ticketClerkAmount");
        number(ticketClerkAmount[i],i,10,0);
        
        tc[i].employeeType="___ticketclerk";
    }
    /*init for the concession clerk*/
    
    for (i = 0; i < MAX_CC; ++i)
    {
        Strcpy(cc[i].lock,"___cclock");
        number(cc[i].lock,i,10,0);

        Strcpy(cc[i].lineCondition,"___cclineCondition");
        number(cc[i].lineCondition,i,10,0);
        
        Strcpy(cc[i].msgCondition,"___ccmsgCondition");
        number(cc[i].msgCondition,i,10,0);

         Strcpy(cc[i].groupId,"___ccgroupId");
        number(cc[i].groupId,i,10,0);

        
        /*Printf("cc[i].lock %d, cc[i].lineCondition %d, cc[i].msgCondition %d\n", cc[i].lock, cc[i].lineCondition, cc[i].msgCondition); */
        Strcpy(cc[i].ticketSum,"___ccticketSum");
        number(cc[i].ticketSum,i,10,0);

        Strcpy(cc[i].isBusy,"___ccisBusy");
        number(cc[i].isBusy,i,10,0);
        
        Strcpy(cc[i].isBreak,"___ccisBreak");
        number(cc[i].isBreak,i,10,0);

        Strcpy(cc[i].waitingSize,"___ccwaitingSize");
        number(cc[i].waitingSize,i,10,0);
        
        Strcpy(cc[i].amount,"___ccamount");
        number(cc[i].amount,i,10,0);
       Strcpy( cc[i].payment,"___ccpayment");
        number(cc[i].payment,i,10,0);
 

        Strcpy(cc[i].food[0],"___ccfood[0]");
        number(cc[i].food[0],i,10,0);
        
        Strcpy(cc[i].food[1],"___ccfood[1]");
        number(cc[i].food[1],i,10,0);
        
        Strcpy(concessionClerkAmount[i],"___concessionClerkAmount");
        number(concessionClerkAmount[i],i,10,0);
        
        cc[i].employeeType="___concessionclerk";
    }
    /*init ticket taker*/ 
    for (i = 0; i < MAX_TT; ++i)
    {
        Strcpy(tt[i].lock,"___ttlock");
        number(tt[i].lock,i,10,0);

        Strcpy(stopTicketTakenArr[i],"___stopTicketTakenArr");
        number(stopTicketTakenArr[i],i,10,0);

        Strcpy(tt[i].lineCondition,"___ttlineCondition");
        number(tt[i].lineCondition,i,10,0);
        
        Strcpy(tt[i].msgCondition,"___ttmsgCondition");
        number(tt[i].msgCondition,i,10,0);

        /*Printf("tt[i].lock %d, tt[i].lineCondition %d, tt[i].msgCondition %d\n", tt[i].lock, tt[i].lineCondition, tt[i].msgCondition); */
        Strcpy(tt[i].ticketSum,"___ttticketSum");
        number(tt[i].ticketSum,i,10,0);

        Strcpy(tt[i].isBusy,"___ttisBusy");
        number(tt[i].isBusy,i,10,0);

        Strcpy(tt[i].groupId,"___ttgroupId");
        number(tt[i].groupId,i,10,0);

        Strcpy(tt[i].isBreak,"___ttisBreak");
        number(tt[i].isBreak,i,10,0);

        Strcpy(tt[i].waitingSize,"___ttwaitingSize");
        number(tt[i].waitingSize,i,10,0);

        
        Strcpy(tt[i].amount,"___ttamount");
        number(tt[i].amount,i,10,0);

        Strcpy(tt[i].payment,"___ttpayment");
        number(tt[i].payment,i,10,0);

        tt[i].employeeType="___tickettaker";
    }
    for(i=0;i<MAX_SEAT;i++){
        Strcpy(seatState[i],"___seatState");
        number(seatState[i],i,10,0);
        
    }

    for(i=0;i<MAX_GROUPSIZE;i++){
        Strcpy(seatLocation[i],"___seatLocation");
        number(seatLocation[i],i,10,0);
    
    }



    Strcpy(mt.lock,"mtlock");

    Strcpy(mt.lineCondition,"mtlineCondition");
    Strcpy(mt.msgCondition,"mtmsgCondition");


    /*Printf("mt.lock %d, mt.lineCondition %d, mt.msgCondition %d\n", mt.lock, mt.lineCondition, mt.msgCondition); */
    Strcpy(mt.ticketSum,"mtticketSum");

   Strcpy( mt.isBusy,"mtisBusy");
 
    
    Strcpy(mt.isBreak,"mtisBreak");

    Strcpy(mt.waitingSize,"mtwaitingSize");

            Strcpy(mt.groupId,"___mtgroupId");
 
    
    Strcpy(mt.amount,"mtamount");;
    
    Strcpy(mt.payment,"mtpayment");

    Strcpy(mr.msgCondition,"mrmsgCondition");


    mr.employeeType="manager";

}

void initTheater()
{
    RT1LO1();

    initRPCVars1();

}


#endif
